/**
  *****************************************************************************
  * @file 
  * @brief 
  * @author  
  * @version
  * @date    2021/07/31
  *****************************************************************************
  */
/* Includes -----------------------------------------------------------------*/
#include "task_lvgl.h"

#include "at32f403a_407_board.h"

#include "statusbar_view.h"

#include "lv_example_anim.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "page.h"
#include "timers.h"

#include "lvgl_module.h"
/* Private defines ----------------------------------------------------------*/
#ifdef 	LVGL_MAIN_TASK_DEBUG_MODE
#define lvgl_main_task_hal_err(...)               do{dbg_printf(__VA_ARGS__);dbg_printf("\r\n");}while(0)
#define lvgl_main_hal_info(...)              			do{dbg_printf(__VA_ARGS__);dbg_printf("\r\n");}while(0)
#define lvgl_main_hal_debug(...)             			do{dbg_printf(__VA_ARGS__);dbg_printf("\r\n");}while(0)
#else
#define lvgl_main_task_hal_err(...)               do{dbg_printf(__VA_ARGS__);dbg_printf("\r\n");}while(0)
#define lvgl_main_task_hal_info(...)              do{dbg_printf(__VA_ARGS__);dbg_printf("\r\n");}while(0)
#define lvgl_main_task_hal_debug(...)
#endif


static void lvgl_gps_client_callback(void* data, int len);
static void lvgl_update_callback(void* parameter);

static notify_node_t notify_node = {
	
	.notify_cb = lvgl_gps_client_callback,	/* lvgl 注册 gps任务的通知 */
	.name = "lvgl_g",
};
/* Private Struct -----------------------------------------------------------*/
 QueueHandle_t lv_key_evt_q = NULL;
 QueueHandle_t lv_dialplate_evt_q = NULL;
/* 软件定时器句柄 */
static TimerHandle_t lvgl_evt_t = NULL;   

TaskHandle_t app_lvgl_handler;
/* Private enum -------------------------------------------------------------*/

/* Private Variable ---------------------------------------------------------*/

/* Private function prototypes ----------------------------------------------*/

void lv_signal_init(void)
{
		lv_key_evt_q = xQueueCreate(LV_TASK_MSG_QUEUE_COUNT, sizeof(EVENT_T));
		{
				if (lv_key_evt_q == NULL)
				{
						lvgl_main_hal_debug("lv_key_evt_q queue create failed");
						/* 没有创建成功,加入创建失败的处理机制 */
				}
		}
		
		lv_dialplate_evt_q = xQueueCreate(LV_TASK_MSG_QUEUE_COUNT, sizeof(EVENT_T));
		{
				if (lv_dialplate_evt_q == NULL)
				{
						lvgl_main_hal_debug("lv_dialplate_evt_q queue create failed");
						/* 没有创建成功,加入创建失败的处理机制 */
				}
		}
}

static void lvgl_timer_init(void)
{		
		lvgl_evt_t = xTimerCreate((const char*		)"lvgl_update_callback",
														 (TickType_t			)500,/* 定时器周期 500(tick) */
														 (UBaseType_t		)pdTRUE,/* 周期模式 */
														 (void*				  )2,/* 为每个计时器分配一个索引的唯一ID */
														 (TimerCallbackFunction_t)lvgl_update_callback); 
		if(lvgl_evt_t == NULL)
		{
				lvgl_main_hal_debug("lvgl_evt_t timer create failed");
				/* 没有创建成功,加入创建失败的处理机制 */
				return;
		}
		/* 开启定时器 */	
		xTimerStart(lvgl_evt_t,0);	
}

BaseType_t lv_evt_message_send(LVGL_EVT_ID EVT_ID, EVENT_T* event, TickType_t wait_tick)
{
		portBASE_TYPE taskWoken = pdFALSE;
		QueueHandle_t *QueueHandle = NULL;
	
		if (EVT_ID == LVGL_EVT_GET_ENCODER_PUSH)
				QueueHandle = &lv_key_evt_q;
		else if (EVT_ID == LVGL_EVT_SHOW)
				QueueHandle = &lv_dialplate_evt_q;
	
		if (__get_IPSR()) 
		{
			 if (xQueueSendFromISR(*QueueHandle, event, &taskWoken) != pdTRUE) 
			 {
					return pdFALSE;
			 }
			 
			 portEND_SWITCHING_ISR(taskWoken);
		}
		else 
		{
			if (xQueueSend(*QueueHandle, event, wait_tick) != pdTRUE) 
			{
				return pdFALSE;
			}
		}
		
		return pdTRUE;
}


BaseType_t lv_evt_message_get(LVGL_EVT_ID EVT_ID, EVENT_T* event, TickType_t wait_tick)
{
		portBASE_TYPE taskWoken = pdFALSE;
		QueueHandle_t *QueueHandle = NULL;
	
		if (EVT_ID == LVGL_EVT_GET_ENCODER_PUSH)
				QueueHandle = &lv_key_evt_q;
		else if (EVT_ID == LVGL_EVT_SHOW)
				QueueHandle = &lv_dialplate_evt_q;
		
		if (__get_IPSR()) 
		{
				if (xQueueReceiveFromISR(*QueueHandle, event, &taskWoken) == pdTRUE) 
				{
						portEND_SWITCHING_ISR(taskWoken);
				}
		}
		else
		{
				return xQueueReceive(*QueueHandle, event, wait_tick);
		}
		
		return pdTRUE;
}

/*****************************************************************************
* @brief  
* ex:
* @par
* None
* @retval
*****************************************************************************/
void task_lvgl(void *arg)
{
	
	/* 注册gps任务的数据通知	*/
	notifier_chain_register(notify_gps_list, &notify_node);
	lvgl_timer_init();
	
  lv_init();
	lv_port_disp_init();	/* 屏幕接口适配 */
	lv_port_indev_init(); /* 编码器初始化 */
	
	page_init();

	default_style();
	
	/* Initialize status bar */
	statusbar_view_create(lv_layer_top());

	page_install("startup");
	page_install("dialplate");
	
	page_start("startup");

  while (1)
  {
    lv_task_handler();
    vTaskDelay(5);
  }
}


/*****************************************************************************
* @brief  定时器回调函数
* ex:
* @par
* None
* @retval
*****************************************************************************/
static void lvgl_update_callback(void* parameter)
{		
		get_module_model_info();
}

static void lvgl_gps_client_callback (void* data, int len)
{
		EVENT_T lv_info;
								
		gps_info_t* gps_info = (gps_info_t*)pvPortMalloc(sizeof(gps_info_t));
		memset(gps_info, 0, sizeof(gps_info_t));
		//lvgl_main_hal_debug("--------------gps_info = %x.", gps_info);

		memcpy(gps_info, (gps_info_t*)data, sizeof(gps_info_t));
	
		//lvgl_main_hal_debug("---------------gps_info = %x.", gps_info);
	
		lv_info.evt_id = LVGL_EVT_SHOW;
		lv_info.param1 = LVGL_EVT_SHOW_NEMA;
		lv_info.param2 = (uint32_t)gps_info;
		if (pdTRUE != lv_evt_message_send(LVGL_EVT_SHOW, &lv_info, TASK_MSG_PUT_TIMEOUT))
		{
				lvgl_main_hal_debug("lvgl send nema message failed");
				/* send failed */
				vPortFree(gps_info);
				//lvgl_main_hal_debug("-------------gps_info = %x.", gps_info);
		}
}
